/*
 * ProcAssignInstruc.java
 * 
 * last update: 24.01.2010 by Olaru Victor
 * 
 * author:	Victor(victor.olaru@gmail.com)
 * 
 * Obs:
 */

package engine;

@SuppressWarnings("serial")
class ProcAssignInstruc extends DefaultInstruction{

	Expression rValue;
	LeftValue lValue;
	Result buffer;      //it keeps the data for delayed assignements
	int delayInside;
	boolean blocking;

	ProcAssignInstruc(NameSpace ns, int delayBefore, InstructionDescription desc ,
			LeftValue lValue,
			Expression rValue, DefaultInstruction next,
			int delayInside, boolean blocking){
		super(ns, delayBefore, desc);
		this.delayInside = delayInside;
		this.rValue = rValue;
		this.lValue = lValue;
		this.delayInside = delayInside;
		this.blocking = blocking;
		add(next);
		buffer = null;

	}

	ProcAssignInstruc(ProcAssignInstruc original){
		super(original.ns, original.delayBefore, original.desc);
		rValue = original.rValue;
		lValue = original.lValue;
		delayInside = original.delayInside;
		blocking = original.blocking;
		buffer = null;
	}

	public Object clone(){
		return new ProcAssignInstruc(this);
	}

	public void execute()
	throws InterpretTimeException, SimulationStoppedException
	{

		long t0 = waitToRun();

		try{
			buffer = rValue.evaluate();
		}catch(InterpretTimeException ex){
			xConsole.dumpStack(ex);
			throw new InterpretTimeException(desc + ": error: " + ex);
		}

		if(delayInside != 0){
			xConsole.trace("#" + delayInside);
			t0 += delayInside;
			while(Time.oClock() < t0)
				ControlThread.goSleepy();
		}
		if(blocking){
			xConsole.trace(toString() + " <<< (" + buffer + ")");
			try{
				lValue.assign(buffer);
			}catch(InterpretTimeException ex){
				xConsole.dumpStack(ex);
				throw new InterpretTimeException(desc + ": error: " + ex);
			}
			Thread.yield();  //give monitors a time to breath

		}else{
			xConsole.trace(toString() + "(cont.)");
			Time.addFinisher(new SimpleAssignInstruction(ns, lValue, buffer,
					this + " <<< (" + buffer + ")"));
		}
	}

	public String toString(){
		return desc.toString();
	}
}
